// StringsExample.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "hwinstring.h"
#include "hwindatetime.h"
#include "hwintext.h"

#include <iostream>
#include <fstream>

#include <atlstr.h>


using namespace harlinn::windows;
using namespace harlinn::windows::text;

void runCompare(const String& s1, const String& s2)
{
    std::wcout << L"Comparing:\"" << (s1?s1:L"") << L"\" and \"" << (s2?s2:L"") << std::endl;
    std::wcout << L"\tbool operator == (const String& other) const returned ";
    if(s1 == s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }
    std::wcout << L"\tbool operator != (const String& other) const returned ";
    if(s1 != s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }

    std::wcout << L"\tbool operator <= (const String& other) const returned ";
    if(s1 <= s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }

    std::wcout << L"\tbool operator < (const String& other) const returned ";
    if(s1 < s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }

    std::wcout << L"\tbool operator >= (const String& other) const returned ";
    if(s1 >= s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }
    std::wcout << L"\tbool operator > (const String& other) const returned ";
    if(s1 > s2)
    {
        std::wcout << "true" << std::endl;
    }
    else
    {
        std::wcout << "false" << std::endl;
    }




}


void runExample()
{
    String s;
    std::wcout << L"Empty string:" << (s?L"Not null" : L"null") << std::endl;

    String sCopy(s);
    std::wcout << L"Copy of empty string:" << (sCopy?L"Not null" : L"null") << std::endl;

    String sFillWithChars(3,L'H');
    std::wcout << L"Filled with chars (3,L'H'):" << sFillWithChars << std::endl;

    String sFillWithChars2(nullptr,1,L"ello",4,L'H');
    std::wcout << L"Filled with chars (nullptr,1,L\"ello\",4,L'H'):" << sFillWithChars2 << std::endl;


    String sFillWithChars3(nullptr,1,L"el",2,L"lo",2,L'H');
    std::wcout << L"Filled with chars (nullptr,1,L\"el\",2,L\"lo\",2,L'H'):" << sFillWithChars3 << std::endl;


    String sCopy2(sFillWithChars3);
    std::wcout << L"Copy of string:" << sCopy2 << std::endl;

    String sPlainString(L"Plain String");
    std::wcout << L"Plain String:" << sPlainString << std::endl;

    s = L"Hello!";
    std::wcout << L"String assignment (const wchar_t*):" << s << std::endl;

    s = s.c_str() + 1;
    std::wcout << L"String assignment from inside string (s = s.c_str() + 1):" << s << std::endl;

    s = sPlainString;
    std::wcout << L"String assignment (const String&):" << s << std::endl;

    String s1 = L"Hello";
    String s2 = L"Hello";

    runCompare(s1,s2);
    s2 = L"Hellp";
    runCompare(s1,s2);

    s2 = L"Helln";
    runCompare(s1,s2);

    String s3 = s1 + s2;
    std::wcout << L"String operator + (const String& str1,const String& str2) returned:" << s3 << std::endl;

    s1 = String();
    s3 = s1 + s2;
    std::wcout << L"String operator + (const String& str1,const String& str2) for empty str1 returned:" << s3 << std::endl;

    s1 = L"Hello";
    s2 = String();
    s3 = s1 + s2;
    std::wcout << L"String operator + (const String& str1,const String& str2) for empty str2 returned:" << s3 << std::endl;


    std::wcout << L"String::size_type pos = s1.IndexOfAnyOf(L\"qwrty\") returned: ";
    String::size_type pos = s1.IndexOfAnyOf(L"qwrty");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wstring ws = L"Hello";
    std::wcout << L"std::wstring::size_type wspos = ws.find_first_of(L\"qwrty\") returned: ";
    std::wstring::size_type wspos = ws.find_first_of(L"qwrty");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.IndexOfAnyOf(L\"olp\") returned: ";
    pos = s1.IndexOfAnyOf(L"olp");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_first_of(L\"olp\") returned: ";
    wspos = ws.find_first_of(L"olp");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.IndexOfAnyBut(L\"olh\") returned: ";
    pos = s1.IndexOfAnyBut(L"olh");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }


    std::wcout << L"std::wstring::size_type wspos = ws.find_first_not_of(L\"olh\") returned: ";
    wspos = ws.find_first_not_of(L"olh");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.IndexOfAnyBut(L\"olhr\") returned: ";
    pos = s1.IndexOfAnyBut(L"olhr");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_first_not_of(L\"olhr\") returned: ";
    wspos = ws.find_first_not_of(L"olhr");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }



    std::wcout << L"String::size_type pos = s1.IndexOfAnyBut(L\"eH\") returned: ";
    pos = s1.IndexOfAnyBut(L"eH");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_first_not_of(L\"eH\") returned: ";
    wspos = ws.find_first_not_of(L"eH");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyOf(L\"qwrty\") returned: ";
    pos = s1.LastIndexOfAnyOf(L"qwrty");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_last_of(L\"qwrty\") returned: ";
    wspos = ws.find_last_of(L"qwrty");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyOf(L\"olp\") returned: ";
    pos = s1.LastIndexOfAnyOf(L"olp");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }


    std::wcout << L"std::wstring::size_type wspos = ws.find_last_of(L\"olp\") returned: ";
    wspos = ws.find_last_of(L"olp");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyOf(L\"hey\") returned: ";
    pos = s1.LastIndexOfAnyOf(L"hey");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_last_of(L\"hey\") returned: ";
    wspos = ws.find_last_of(L"hey");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }



    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyOf(L\"zxcH\") returned: ";
    pos = s1.LastIndexOfAnyOf(L"zxcH");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_last_of(L\"zxcH\") returned: ";
    wspos = ws.find_last_of(L"zxcH");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyBut(L\"o\") returned: ";
    pos = s1.LastIndexOfAnyBut(L"o");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_last_not_of(L\"o\") returned: ";
    wspos = ws.find_last_not_of(L"o");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.LastIndexOfAnyBut(L\"ol\") returned: ";
    pos = s1.LastIndexOfAnyBut(L"ol");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find_last_not_of(L\"ol\") returned: ";
    wspos = ws.find_last_not_of(L"ol");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.IndexOf(L\"qwrt\") returned: ";
    pos = s1.IndexOf(L"qwrt");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"qwrt\") returned: ";
    wspos = ws.find(L"qwrt");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.IndexOf(L\"H\") returned: ";
    pos = s1.IndexOf(L"H");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"H\") returned: ";
    wspos = ws.find(L"H");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.IndexOf(L\"He\") returned: ";
    pos = s1.IndexOf(L"He");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"He\") returned: ";
    wspos = ws.find(L"He");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.IndexOf(L\"o\") returned: ";
    pos = s1.IndexOf(L"o");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"o\") returned: ";
    wspos = ws.find(L"o");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.IndexOf(L\"lo\") returned: ";
    pos = s1.IndexOf(L"lo");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"lo\") returned: ";
    wspos = ws.find(L"lo");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.IndexOf(L\"ll\") returned: ";
    pos = s1.IndexOf(L"ll");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.find(L\"ll\") returned: ";
    wspos = ws.find(L"ll");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"qwrt\") returned: ";
    pos = s1.LastIndexOf(L"qwrt");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"qwrt\") returned: ";
    wspos = ws.rfind(L"qwrt");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"ll\") returned: ";
    pos = s1.LastIndexOf(L"ll");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"ll\") returned: ";
    wspos = ws.rfind(L"ll");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"H\") returned: ";
    pos = s1.LastIndexOf(L"H");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"H\") returned: ";
    wspos = ws.rfind(L"H");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"He\") returned: ";
    pos = s1.LastIndexOf(L"He");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"He\") returned: ";
    wspos = ws.rfind(L"He");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }


    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"o\") returned: ";
    pos = s1.LastIndexOf(L"o");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"o\") returned: ";
    wspos = ws.rfind(L"o");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf(L\"lo\") returned: ";
    pos = s1.LastIndexOf(L"lo");
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"std::wstring::size_type wspos = ws.rfind(L\"lo\") returned: ";
    wspos = ws.rfind(L"lo");
    if(wspos == std::wstring::npos)
    {
        std::wcout << L"std::wstring::npos" << std::endl;
    }
    else
    {
        std::wcout << wspos << std::endl;
    }

    wchar_t wbuffer[10] = {0,};

    std::wcout << L"s1.CopyTo(wbuffer,1) copied: ";
    s1.CopyTo(wbuffer,1);
    std::wcout << wbuffer << std::endl;

    std::wcout << L"ws.copy(wbuffer,1) copied: ";
    ws.copy(wbuffer,1);
    std::wcout << wbuffer << std::endl;


    std::wcout << L"s1.CopyTo(wbuffer,1,4) copied: ";
    s1.CopyTo(wbuffer,1,4);
    std::wcout << wbuffer << std::endl;

    std::wcout << L"ws.copy(wbuffer,1,4) copied: ";
    ws.copy(wbuffer,1,4);
    std::wcout << wbuffer << std::endl;

    
    std::wcout << L"s2 = s1.SubString(0) copied: ";
    s2 = s1.SubString(0);
    std::wcout << s2 << std::endl;

    std::wcout << L"ws2 = ws.substr(0) copied: ";
    std::wstring ws2 = ws.substr(0);
    std::wcout << ws2 << std::endl;

    std::wcout << L"s2 = s1.SubString(1,2) copied: ";
    s2 = s1.SubString(1,2);
    std::wcout << s2 << std::endl;

    std::wcout << L"ws2 = ws.substr(1,2) copied: ";
    ws2 = ws.substr(1,2);
    std::wcout << ws2 << std::endl;

    s2 = s1;
    std::wcout << L"s2.UpperCase(): ";
    s2.UpperCase();
    std::wcout << s2 << std::endl;

    s2 = s1;
    std::wcout << L"s2.LowerCase(): ";
    s2.LowerCase();
    std::wcout << s2 << std::endl;


    s2 = s1;
    std::wcout << L"s2.Remove(0): ";
    s2.Remove(0);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    ws2 = ws;
    std::wcout << L"ws2.erase(0): ";
    ws2.erase(0);
    std::wcout << ws2 << std::endl;


    s2 = s1;
    std::wcout << L"s2.Remove(0,0): ";
    s2.Remove(0,0);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    ws2 = ws;
    std::wcout << L"ws2.erase(0,0): ";
    ws2.erase(0,0);
    std::wcout << ws2 << std::endl;

    s2 = s1;
    std::wcout << L"s2.Remove(0,1): ";
    s2.Remove(0,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    ws2 = ws;
    std::wcout << L"ws2.erase(0,1): ";
    ws2.erase(0,1);
    std::wcout << ws2 << std::endl;


    s2 = s1;
    std::wcout << L"s2.Remove(4,1): ";
    s2.Remove(4,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    ws2 = ws;
    std::wcout << L"ws2.erase(4,1): ";
    ws2.erase(4,1);
    std::wcout << ws2 << std::endl;

    s2 = s1;
    std::wcout << L"s2.RemoveRange(4,5): ";
    s2.RemoveRange(4,5);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.RemoveRange(0,1): ";
    s2.RemoveRange(0,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.RemoveRange(1,2): ";
    s2.RemoveRange(1,2);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.Keep(0): ";
    s2.Keep(0);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(1): ";
    s2.Keep(1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.Keep(0,1): ";
    s2.Keep(0,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(0,2): ";
    s2.Keep(0,2);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(1,1): ";
    s2.Keep(1,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(1,2): ";
    s2.Keep(1,2);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(5): ";
    s2.Keep(5);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.Keep(3,6): ";
    s2.Keep(3,6);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Keep(5,6): ";
    s2.Keep(5,6);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.KeepRange(0,0): ";
    s2.KeepRange(0,0);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.KeepRange(0,1): ";
    s2.KeepRange(0,1);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.KeepRange(0,2): ";
    s2.KeepRange(0,2);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.KeepRange(1,3): ";
    s2.KeepRange(1,3);
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.KeepRange(5,6): ";
    s2.KeepRange(5,6);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.Insert(L\"Say \"): ";
    s2.Insert(L"Say ");
    std::wcout << (s2?s2:L"nullptr") << std::endl;

    s2 = s1;
    std::wcout << L"s2.Insert(L\" world\",100): ";
    s2.Insert(L" world",100);
    std::wcout << (s2?s2:L"nullptr") << std::endl;


    s2 = s1;
    std::wcout << L"s2.TrimRight(): ";
    s2.TrimRight();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;

    s2 = s1;
    std::wcout << L"s2.TrimLeft(): ";
    s2.TrimLeft();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;


    s2 = s1;
    std::wcout << L"s2.Trim(): ";
    s2.Trim();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;

    s1 = L"  hello  ";

    s2 = s1;
    std::wcout << L"s2.TrimRight(): ";
    s2.TrimRight();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;

    s2 = s1;
    std::wcout << L"s2.TrimLeft(): ";
    s2.TrimLeft();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;


    s2 = s1;
    std::wcout << L"s2.Trim(): ";
    s2.Trim();
    std::wcout << L'\'' <<(s2?s2:L"nullptr") << L'\'' << std::endl;


    s1 = L"   ";

    s2 = s1;
    std::wcout << L"s2.TrimRight(): ";
    s2.TrimRight();
    std::wcout << L'\'' <<(s2?s2:L"") << L'\'' << std::endl;

    s2 = s1;
    std::wcout << L"s2.TrimLeft(): ";
    s2.TrimLeft();
    std::wcout << L'\'' <<(s2?s2:L"") << L'\'' << std::endl;


    s2 = s1;
    std::wcout << L"s2.Trim(): ";
    s2.Trim();
    std::wcout << L'\'' <<(s2?s2:L"") << L'\'' << std::endl;
    
    s1 = L"Hello";

    for(auto c : s1)
    {
        std::wcout << L'\'' << c << L'\'' << std::endl;
    }

    for(auto& c : s1)
    {
        c = c+1;
    }

    for(auto& c : s1)
    {
        std::wcout << L'\'' << c << L'\'' << std::endl;
    }


    s1 = String();

    for(auto c : s1)
    {
        std::wcout << L'\'' << L"This should not happen" << L'\'' << std::endl;
    }



    s1 = L"Hello";

    
    std::wcout << L"String::size_type pos = s1.IndexOf([](wchar_t c) -> bool {...}) returned: ";
    pos = s1.IndexOf([](wchar_t c) -> bool
    {
        return c == L'l';
    });
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }

    std::wcout << L"String::size_type pos = s1.LastIndexOf([](wchar_t c) -> bool {...}) returned: ";
    pos = s1.LastIndexOf([](wchar_t c) -> bool
    {
        return c == L'l';
    });
    if(pos == String::npos)
    {
        std::wcout << L"String::npos" << std::endl;
    }
    else
    {
        std::wcout << pos << std::endl;
    }
    



}


void StringVectorOfEmptyStringsInitialize()
{
    std::vector<String> v;
    Stopwatch stopwatch;
    stopwatch.Start();
    v.resize(100000);
    stopwatch.Stop();
    std::wcout << L"std::vector<String> v; v.resize(100000); " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorOfEmptyStringsInitialize()
{
    std::vector<std::wstring> v;
    Stopwatch stopwatch;
    stopwatch.Start();
    v.resize(100000);
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> v; v.resize(100000); " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorOfEmptyStringsInitialize()
{
    std::vector<CStringW> v;
    Stopwatch stopwatch;
    stopwatch.Start();
    v.resize(100000);
    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> v; v.resize(100000); " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


//wchar_t* smallStrings[] = {L"The",L"Quick",L"Fox",L"Jumped"};
/*
std::vector<String> v; v.resize(100000); 0.4088
std::vector<std::wstring> v; v.resize(100000); 1.5721
std::vector<String> initialize with small strings: 14.1969
std::vector<std::wstring> initialize with small strings: 4.6244
std::vector<String> Get total length (425000) : 2.4355
std::vector<std::wstring> Get total length (425000) : 3.5326
std::vector<String> assign to: 1.8704
std::vector<std::wstring> assign to: 3.6208
std::vector<String> initialize with small strings push_back: 11.7914
std::vector<std::wstring> initialize with small strings push_back: 4.5539
std::vector<String> initialize with small strings: 8.9747
std::vector<std::wstring> initialize with small strings: 2.8478
std::vector<String> append to: 3.645
std::vector<std::wstring> append to: 5.4127
*/
wchar_t* smallStrings[] = {L"C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0A\\Include",
    L"C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0A\\lib",
    L"C:\\VS11\\VC\\atlmfc\\include",
    L"C:\\VS11\\VC\\lib"
};

void StringVectorInitializeSmallStrings(std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i] = smallStrings[i%4];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> initialize with small strings: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorInitializeSmallStrings(std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i] = smallStrings[i%4];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> initialize with small strings: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}





void CStringVectorInitializeSmallStrings(std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i] = smallStrings[i%4];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> initialize with small strings: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorGetTotalLength(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000;i++)
    {
        totalLength += v[i].length();
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> Get total length (" << totalLength << L") : " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorGetTotalLength(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000;i++)
    {
        totalLength += v[i].length();
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> Get total length (" << totalLength << L") : " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorGetTotalLength(const std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000;i++)
    {
        const auto& s = v[i];
        totalLength += s.GetLength();
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> Get total length (" << totalLength << L") : " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void StringVectorAssignTo(const std::vector<String>& v,std::vector<String>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] = v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> assign to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorAssignTo(const std::vector<std::wstring>& v,std::vector<std::wstring>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] = v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> assign to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorAssignTo(const std::vector<CStringW>& v,std::vector<CStringW>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] = v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> assign to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorInitializeSmallStringsPushBack(std::vector<String>& v)
{
    Stopwatch stopwatch;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v.push_back(String( smallStrings[i%4] ));
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> initialize with small strings push_back: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorInitializeSmallStringsPushBack(std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v.push_back(std::wstring( smallStrings[i%4] ));
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> initialize with small strings push_back: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorInitializeSmallStringsPushBack(std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v.push_back(CStringW( smallStrings[i%4] ));
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> initialize with small strings push_back: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorAppendTo(std::vector<String>& v,std::vector<String>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] += v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> append to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorAppendTo(std::vector<std::wstring>& v,std::vector<std::wstring>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] += v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> append to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorAppendTo(std::vector<CStringW>& v,std::vector<CStringW>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        v2[i] += v[i];
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> append to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorAppendCharTo(std::vector<String>& v,std::vector<String>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        auto& dest = v2[i];
        auto destLength = dest.length();
        auto& source = v[i];
        auto sourceLength = source.length();
        for(size_t i = 0; i < 10; i++)
        {
            for(decltype(sourceLength) ii = 0; ii < sourceLength; ii++)
            {
                wchar_t c = source[ii];
                dest += c;
            }
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> append char to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringBuilderVectorAppendCharTo(std::vector<String>& v,std::vector<StringBuilder>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        auto& dest = v2[i];
        auto& source = v[i];
        auto sourceLength = source.length();
        for(size_t i = 0; i < 10; i++)
        {
            for(decltype(sourceLength) ii = 0; ii < sourceLength; ii++)
            {
                wchar_t c = source[ii];
                dest += c;
            }
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<StringBuilder> append char to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringBuilderVectorAppendCharTo(std::vector<String>& v,std::vector<String>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        auto& dest = v2[i];
        auto& source = v[i];
        auto sourceLength = source.length();
        for(size_t iii = 0; iii < 10; iii++)
        {
            StringBuilder sb;
            for(decltype(sourceLength) ii = 0; ii < sourceLength; ii++)
            {
                wchar_t c = source[ii];
                sb += c;
            }
            dest += sb.ToString();
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> StringBuilder append char to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorAppendCharTo(std::vector<std::wstring>& v,std::vector<std::wstring>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        auto& dest = v2[i];
        auto destLength = dest.length();
        auto& source = v[i];
        auto sourceLength = source.length();
        for(size_t iii = 0; iii < 10; iii++)
        {
            for(decltype(sourceLength) ii = 0; ii < sourceLength; ii++)
            {
                wchar_t c = source[ii];
                dest += c;
            }
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> append char to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorAppendCharTo(std::vector<CStringW>& v,std::vector<CStringW>& v2)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    for(size_t i = 0; i < 100000; i++)
    {
        auto& dest = v2[i];
        auto destLength = dest.GetLength();
        auto& source = v[i];
        auto sourceLength = source.GetLength();
        for(size_t iii = 0; iii < 10; iii++)
        {
            for(decltype(sourceLength) ii = 0; ii < sourceLength; ii++)
            {
                wchar_t c = source[ii];
                dest += c;
            }
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> append char to: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorSort(std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    std::sort(v.begin(),v.end());

    stopwatch.Stop();
    std::wcout << L"std::vector<String> sort: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorSort(std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    std::sort(v.begin(),v.end());

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> sort: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorSort(std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalLength = 0;
    stopwatch.Start();

    std::sort(v.begin(),v.end());

    stopwatch.Stop();
    std::wcout << L"std::vector<String> sort: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void StringVectorSimpleIndexOfAnyOf(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = s.IndexOfAnyOf(L"7b");
        
        if(pos != String::npos)
        {
            found++;
        }
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> Simple IndexOfAnyOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorSimple_find_first_of(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = s.find_first_of(L"7b");
        
        if(pos != String::npos)
        {
            found++;
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> Simple find_first_of:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorSimpleFindOneOf(const std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = s.FindOneOf(L"7b");
        
        if(pos != String::npos)
        {
            found++;
        }
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> Simple IndexOfAnyOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorIndexOfAnyOf(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.IndexOfAnyOf(L"\\/",start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> IndexOfAnyOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVector_find_first_of(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.find_first_of(L"\\/",start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> find_first_of:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}



void StringVectorLastIndexOfAnyOf(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = s.length();
        do
        {
            pos = s.LastIndexOfAnyOf(L"\\/",start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> LastIndexOfAnyOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVector_find_last_of(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = s.length();
        do
        {
            pos = s.find_last_of(L"\\/",start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> find_last_of:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void StringVectorIndexOf(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.IndexOf(L"lib",start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> IndexOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVector_find(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.find(L"lib",start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> find:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorFind(const std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.Find(L"lib",start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> Find:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorIndexOfChar(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = 0;
        do
        {
            pos = s.IndexOf(L'7',start);
            if(pos != String::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> IndexOf char:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorIndexOfChar(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = std::wstring::npos;
        size_t start = 0;
        do
        {
            pos = s.find(L'7',start);
            if(pos != std::wstring::npos)
            {
                start = pos +1;
                found++;
            }

        }while(pos != std::wstring::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> find char:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorIndexOfChar(const std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        int pos = -1;
        int start = 0;
        do
        {
            pos = s.Find(L'7',start);
            if(pos >= 0)
            {
                start = pos +1;
                found++;
            }

        }while(pos >= 0);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> Find char:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}



void StringVectorLastIndexOf(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = String::npos;
        do
        {
            pos = s.LastIndexOf(L"lib",start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> LastIndexOf:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVector_rfind(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = std::wstring::npos;
        size_t start = std::wstring::npos;
        do
        {
            pos = s.rfind(L"lib",start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> rfind:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorLastIndexOfChar(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = String::npos;
        size_t start = String::npos;
        do
        {
            pos = s.LastIndexOf(L'7',start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != String::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<String> LastIndexOf char:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorLastIndexOfChar(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();
    size_t found = 0;

    for(auto& s : v)
    {
        size_t pos = std::wstring::npos;
        size_t start = std::wstring::npos;
        do
        {
            pos = s.rfind(L'7',start);
            if(pos != String::npos)
            {
                start = pos -1;
                found++;
            }

        }while(pos && pos != std::wstring::npos);
        
    }
    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> rfind char:("<< found << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorInsertString(std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].Insert(L"Text",3);
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> insert string: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorInsertString(std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].insert(3,L"Text");
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> insert string: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void CStringVectorInsertString(std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].Insert(3,L"Text");
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> insert string: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorRemove(std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].Remove(2,3);
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> remove: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void wstringVectorRemove(std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].erase(2,3);
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> remove: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorRemove(std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    stopwatch.Start();

    for(size_t i = 0; i < size; i++)
    {
        v[i].Delete(2,3);
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> remove: " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


void StringVectorDataAccess(const std::vector<String>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalBS = 0;
    stopwatch.Start();

    for(int ii = 0; ii < 1000;ii++)
    {
        for(size_t i = 0; i < size; i++)
        {
            const wchar_t* p = v[i].c_str();
            totalBS += *p;
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<String> data access: ("<< totalBS << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringVectorDataAccess(const std::vector<std::wstring>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalBS = 0;
    stopwatch.Start();

    for(int ii = 0; ii < 1000;ii++)
    {
        for(size_t i = 0; i < size; i++)
        {
            const wchar_t* p = v[i].c_str();
            totalBS += *p;
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<std::wstring> data access: ("<< totalBS << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringVectorDataAccess(const std::vector<CStringW>& v)
{
    Stopwatch stopwatch;
    size_t size = v.size();
    size_t totalBS = 0;
    stopwatch.Start();

    for(int ii = 0; ii < 1000;ii++)
    {
        for(size_t i = 0; i < size; i++)
        {
            const wchar_t* p = v[i];
            totalBS += *p;
        }
    }

    stopwatch.Stop();
    std::wcout << L"std::vector<CStringW> data access: ("<< totalBS << L") " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

const size_t maxRecursion = 10000;

String StringRecursion(const String& arg,size_t recursionLevel)
{
    String result = arg + L"Hi";
    if(recursionLevel < maxRecursion)
    {
        recursionLevel++;
        result = StringRecursion(result,recursionLevel);
    }
    return result;
}

std::wstring StringRecursion(const std::wstring& arg,size_t recursionLevel)
{
    std::wstring result = arg + L"Hi";
    if(recursionLevel < maxRecursion)
    {
        recursionLevel++;
        result = StringRecursion(result,recursionLevel);
    }
    return result;
}

CStringW StringRecursion(const CStringW& arg,size_t recursionLevel)
{
    CStringW result = arg + L"Hi";
    if(recursionLevel < maxRecursion)
    {
        recursionLevel++;
        result = StringRecursion(result,recursionLevel);
    }
    return result;
}


void StringRecursion( )
{
    Stopwatch stopwatch;
    stopwatch.Start();
    String s = L"String";

    s = StringRecursion(s,0);

    stopwatch.Stop();
    std::wcout << L"String recursion(" << s.length() << L" ): " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void wstringRecursion( )
{
    Stopwatch stopwatch;
    stopwatch.Start();
    std::wstring s = L"String";

    s = StringRecursion(s,0);

    stopwatch.Stop();
    std::wcout << L"std::wstring recursion (" << s.length() << L" ): " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}

void CStringRecursion( )
{
    Stopwatch stopwatch;
    stopwatch.Start();
    CStringW s = L"String";

    s = StringRecursion(s,0);

    stopwatch.Stop();
    std::wcout << L"CStringW recursion(" << s.GetLength() << L" ): " << stopwatch.Elapsed().TotalMilliseconds() << std::endl;
}


int _tmain(int argc, _TCHAR* argv[])
{
    //runExample();

    std::wcout << L"sizeof(String): " << sizeof(String)  << std::endl;
    std::wcout << L"sizeof(std::wstring): " << sizeof(std::wstring)  << std::endl;
    std::wcout << L"sizeof(CStringW): " << sizeof(CStringW)  << std::endl;

    std::wcout << std::endl;

    std::vector<String> strings;
    std::vector<std::wstring> wstrings;
    std::vector<CStringW> cstrings;

    std::vector<String> strings2;
    std::vector<std::wstring> wstrings2;
    std::vector<CStringW> cstrings2;

    strings.resize(100000);
    wstrings.resize(100000);
    cstrings.resize(100000);

    strings2.resize(100000);
    wstrings2.resize(100000);
    cstrings2.resize(100000);

    StringVectorOfEmptyStringsInitialize();
    wstringVectorOfEmptyStringsInitialize();
    CStringVectorOfEmptyStringsInitialize();

    std::wcout << std::endl;

    StringVectorInitializeSmallStrings(strings);
    wstringVectorInitializeSmallStrings(wstrings);
    CStringVectorInitializeSmallStrings(cstrings);

    std::wcout << std::endl;

    StringVectorGetTotalLength(strings);
    wstringVectorGetTotalLength(wstrings);
    CStringVectorGetTotalLength(cstrings);

    std::wcout << std::endl;

    StringVectorAssignTo(strings,strings2);
    wstringVectorAssignTo(wstrings,wstrings2);
    CStringVectorAssignTo(cstrings,cstrings2);
    std::wcout << std::endl;

    std::vector<String> strings3;
    strings3.reserve(100000);

    std::vector<std::wstring> wstrings3;
    wstrings3.reserve(100000);

    std::vector<CStringW> cstrings3;
    cstrings3.reserve(100000);


    StringVectorInitializeSmallStringsPushBack(strings3);
    wstringVectorInitializeSmallStringsPushBack(wstrings3);
    CStringVectorInitializeSmallStringsPushBack(cstrings3);
    std::wcout << std::endl;

    std::vector<String> strings4;
    std::vector<std::wstring> wstrings4;
    std::vector<CStringW> cstrings4;

    strings4.resize(100000);
    wstrings4.resize(100000);
    cstrings4.resize(100000);
    StringVectorInitializeSmallStrings(strings4);
    wstringVectorInitializeSmallStrings(wstrings4);
    CStringVectorInitializeSmallStrings(cstrings4);
    std::wcout << std::endl;

    StringVectorAppendTo(strings3,strings4);
    wstringVectorAppendTo(wstrings3,wstrings4);
    CStringVectorAppendTo(cstrings3,cstrings4);
    std::wcout << std::endl;

    std::vector<StringBuilder> stringBuilders;
    stringBuilders.resize(100000);
    for(size_t i = 0; i < 100000;i++)
    {
        stringBuilders[i].Append(strings4[i]);
    }

    std::vector<String> strings5 = strings4;

    StringVectorAppendCharTo(strings3,strings4);
    StringBuilderVectorAppendCharTo(strings3,stringBuilders);
    StringBuilderVectorAppendCharTo(strings3,strings5);
    wstringVectorAppendCharTo(wstrings3,wstrings4);
    CStringVectorAppendCharTo(cstrings3,cstrings4);
    std::wcout << std::endl;

    StringVectorSort(strings4);
    wstringVectorSort(wstrings4);
    CStringVectorSort(cstrings4);
    std::wcout << std::endl;

    StringVectorSimpleIndexOfAnyOf(strings4);
    wstringVectorSimple_find_first_of(wstrings4);
    CStringVectorSimpleFindOneOf(cstrings4);
    std::wcout << std::endl;

    StringVectorIndexOfAnyOf(strings4);
    wstringVector_find_first_of(wstrings4);
    std::wcout << std::endl;

    StringVectorLastIndexOfAnyOf(strings4);
    wstringVector_find_last_of(wstrings4);
    std::wcout << std::endl;

    StringVectorIndexOf(strings4);
    wstringVector_find(wstrings4);
    CStringVectorFind(cstrings4);
    std::wcout << std::endl;

    StringVectorLastIndexOf(strings4);
    wstringVector_rfind(wstrings4);
    std::wcout << std::endl;

    StringVectorIndexOfChar(strings4);
    wstringVectorIndexOfChar(wstrings4);
    CStringVectorIndexOfChar(cstrings4);
    std::wcout << std::endl;

    StringVectorLastIndexOfChar(strings4);
    wstringVectorLastIndexOfChar(wstrings4);
    std::wcout << std::endl;


    StringVectorInsertString(strings4);
    wstringVectorInsertString(wstrings4);
    CStringVectorInsertString(cstrings4);
    std::wcout << std::endl;


    StringVectorRemove(strings4);
    wstringVectorRemove(wstrings4);
    CStringVectorRemove(cstrings4);
    std::wcout << std::endl;

    StringVectorDataAccess(strings4);
    wstringVectorDataAccess(wstrings4);
    CStringVectorDataAccess(cstrings4);
    std::wcout << std::endl;

    StringRecursion( );
    wstringRecursion( );
    CStringRecursion( );
    std::wcout << std::endl;



	return 0;
}

